<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>HashMap 扩容机制深度解析</title>
    <link href="https://cdn.staticfile.org/font-awesome/6.4.0/css/all.min.css" rel="stylesheet">
    <link href="https://cdn.staticfile.org/tailwindcss/2.2.19/tailwind.min.css" rel="stylesheet">
    <link href="https://fonts.googleapis.com/css2?family=Noto+Serif+SC:wght@400;500;600;700&family=Noto+Sans+SC:wght@300;400;500;700&display=swap" rel="stylesheet">
    <script src="https://cdn.jsdelivr.net/npm/mermaid@latest/dist/mermaid.min.js"></script>
    <style>
        body {
            font-family: 'Noto Sans SC', Tahoma, Arial, Roboto, "Droid Sans", "Helvetica Neue", "Droid Sans Fallback", "Heiti SC", "Hiragino Sans GB", Simsun, sans-serif;
            background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);
            min-height: 100vh;
        }
        
        .hero-gradient {
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
        }
        
        .card-hover {
            transition: all 0.3s ease;
        }
        
        .card-hover:hover {
            transform: translateY(-5px);
            box-shadow: 0 20px 40px rgba(0,0,0,0.1);
        }
        
        .text-gradient {
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            -webkit-background-clip: text;
            -webkit-text-fill-color: transparent;
            background-clip: text;
        }
        
        .drop-cap {
            float: left;
            font-size: 4rem;
            line-height: 1;
            font-weight: 700;
            margin-right: 0.5rem;
            margin-top: -0.2rem;
            color: #667eea;
        }
        
        .code-highlight {
            background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%);
            color: white;
            padding: 0.2rem 0.6rem;
            border-radius: 0.375rem;
            font-family: 'Courier New', monospace;
            font-weight: 600;
        }
        
        .section-divider {
            height: 2px;
            background: linear-gradient(to right, transparent, #667eea, transparent);
            margin: 3rem 0;
        }
        
        .mermaid {
            display: flex;
            justify-content: center;
            margin: 2rem 0;
        }
        
        .icon-box {
            width: 60px;
            height: 60px;
            display: flex;
            align-items: center;
            justify-content: center;
            border-radius: 1rem;
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            color: white;
            font-size: 1.5rem;
            margin-bottom: 1rem;
        }
        
        .timeline-item {
            position: relative;
            padding-left: 3rem;
            padding-bottom: 2rem;
        }
        
        .timeline-item::before {
            content: '';
            position: absolute;
            left: 0.75rem;
            top: 0.5rem;
            width: 0.5rem;
            height: 0.5rem;
            background: #667eea;
            border-radius: 50%;
        }
        
        .timeline-item::after {
            content: '';
            position: absolute;
            left: 0.9375rem;
            top: 1rem;
            width: 2px;
            height: calc(100% - 1rem);
            background: #e5e7eb;
        }
        
        .timeline-item:last-child::after {
            display: none;
        }
    </style>
</head>
<body>
    <!-- Hero Section -->
    <section class="hero-gradient text-white py-20">
        <div class="container mx-auto px-6">
            <div class="max-w-4xl mx-auto text-center">
                <h1 class="text-5xl md:text-6xl font-bold mb-6">
                    HashMap 扩容机制
                </h1>
                <p class="text-xl md:text-2xl opacity-90 mb-8">
                    深入理解 Java 集合框架的核心优化策略
                </p>
                <div class="flex justify-center space-x-4">
                    <span class="bg-white bg-opacity-20 px-4 py-2 rounded-full">
                        <i class="fas fa-expand-arrows-alt mr-2"></i>动态扩容
                    </span>
                    <span class="bg-white bg-opacity-20 px-4 py-2 rounded-full">
                        <i class="fas fa-tachometer-alt mr-2"></i>性能优化
                    </span>
                    <span class="bg-white bg-opacity-20 px-4 py-2 rounded-full">
                        <i class="fas fa-cogs mr-2"></i>负载均衡
                    </span>
                </div>
            </div>
        </div>
    </section>

    <!-- Main Content -->
    <main class="container mx-auto px-6 py-12 max-w-6xl">
        <!-- Introduction Card -->
        <div class="bg-white rounded-2xl shadow-xl p-8 mb-12 card-hover">
            <p class="text-lg leading-relaxed text-gray-700">
                <span class="drop-cap">在</span>HashMap 中，当需要存储的键值对数量超过了当前容量所能容纳的上限时，就会触发扩容（resize）操作。扩容的目的是增加哈希表的容量，以减少哈希冲突并提高访问效率。但也会带来一定的性能开销。因此，在使用 <span class="code-highlight">HashMap</span> 时，合理地设置初始容量和负载因子，可以减少扩容的频率，从而提升性能。
            </p>
        </div>

        <!-- Core Concepts Grid -->
        <div class="grid md:grid-cols-2 gap-8 mb-12">
            <!-- Capacity Card -->
            <div class="bg-white rounded-2xl shadow-lg p-8 card-hover">
                <div class="icon-box">
                    <i class="fas fa-database"></i>
                </div>
                <h3 class="text-2xl font-bold mb-4 text-gray-800">容量 (Capacity)</h3>
                <p class="text-gray-600 leading-relaxed">
                    <span class="code-highlight">HashMap</span> 的容量是桶数组的长度，即可以存储的键值对的最大数量（不考虑哈希冲突）。容量必须是2的幂次方，这样可以通过位运算快速定位元素位置。
                </p>
            </div>

            <!-- Load Factor Card -->
            <div class="bg-white rounded-2xl shadow-lg p-8 card-hover">
                <div class="icon-box">
                    <i class="fas fa-percentage"></i>
                </div>
                <h3 class="text-2xl font-bold mb-4 text-gray-800">负载因子 (Load Factor)</h3>
                <p class="text-gray-600 leading-relaxed">
                    负载因子是一个用于衡量 <span class="code-highlight">HashMap</span> 装满程度的参数，默认为 <span class="code-highlight">0.75</span>。它表示在触发扩容之前，HashMap 能够使用的容量比例。
                </p>
            </div>
        </div>

        <!-- Threshold Visualization -->
        <div class="bg-gradient-to-r from-purple-50 to-pink-50 rounded-2xl p-8 mb-12">
            <h2 class="text-3xl font-bold mb-6 text-center text-gradient">阈值计算公式</h2>
            <div class="bg-white rounded-xl p-6 text-center">
                <p class="text-2xl font-mono text-gray-800">
                    阈值 (threshold) = 容量 × 负载因子
                </p>
                <p class="text-gray-600 mt-4">
                    当 HashMap 中的键值对数量超过这个阈值时，就会触发扩容
                </p>
            </div>
        </div>

        <!-- Resize Process Timeline -->
        <section class="mb-12">
            <h2 class="text-3xl font-bold mb-8 text-gray-800">
                <i class="fas fa-clock mr-3 text-purple-600"></i>扩容触发时机
            </h2>
            <div class="bg-white rounded-2xl shadow-lg p-8">
                <div class="timeline-item">
                    <h4 class="text-xl font-semibold text-gray-800 mb-2">插入新键值对时</h4>
                    <p class="text-gray-600">
                        每当向 <span class="code-highlight">HashMap</span> 插入一个新的键值对时，HashMap 会检查当前存储的键值对数量是否已经超过了阈值。如果超过了，则会触发扩容。
                    </p>
                </div>
                <div class="timeline-item">
                    <h4 class="text-xl font-semibold text-gray-800 mb-2">初始化时指定较小的容量</h4>
                    <p class="text-gray-600">
                        如果在 <span class="code-highlight">HashMap</span> 初始化时指定了较小的容量，但随着插入的数据增多，超过了由初始容量和负载因子计算得出的阈值，也会触发扩容。
                    </p>
                </div>
            </div>
        </section>

        <!-- Resize Operations -->
        <section class="mb-12">
            <h2 class="text-3xl font-bold mb-8 text-gray-800">
                <i class="fas fa-cog mr-3 text-purple-600"></i>扩容的具体操作
            </h2>
            <div class="grid md:grid-cols-3 gap-6">
                <div class="bg-white rounded-xl shadow-lg p-6 card-hover">
                    <div class="text-4xl text-purple-600 mb-4 text-center">
                        <i class="fas fa-plus-square"></i>
                    </div>
                    <h4 class="text-xl font-semibold mb-3 text-center">创建新数组</h4>
                    <p class="text-gray-600 text-center">
                        新数组的容量通常是旧数组容量的两倍，降低哈希冲突概率
                    </p>
                </div>
                <div class="bg-white rounded-xl shadow-lg p-6 card-hover">
                    <div class="text-4xl text-purple-600 mb-4 text-center">
                        <i class="fas fa-calculator"></i>
                    </div>
                    <h4 class="text-xl font-semibold mb-3 text-center">重新计算哈希</h4>
                    <p class="text-gray-600 text-center">
                        将原数组中的所有键值对重新哈希，计算在新数组中的位置
                    </p>
                </div>
                <div class="bg-white rounded-xl shadow-lg p-6 card-hover">
                    <div class="text-4xl text-purple-600 mb-4 text-center">
                        <i class="fas fa-exchange-alt"></i>
                    </div>
                    <h4 class="text-xl font-semibold mb-3 text-center">迁移数据</h4>
                    <p class="text-gray-600 text-center">
                        将旧数组中的所有键值对迁移到新数组，更新位置信息
                    </p>
                </div>
            </div>
        </section>

        <!-- Visual Diagram -->
        <section class="mb-12">
            <h2 class="text-3xl font-bold mb-8 text-gray-800">
                <i class="fas fa-project-diagram mr-3 text-purple-600"></i>扩容过程可视化
            </h2>
            <div class="bg-white rounded-2xl shadow-lg p-8">
                <div class="mermaid">
                    graph LR
                        A[原始HashMap<br/>容量: 16<br/>阈值: 12] -->|插入第13个元素| B[触发扩容]
                        B --> C[创建新数组<br/>容量: 32]
                        C --> D[重新计算哈希值]
                        D --> E[数据迁移]
                        E --> F[新HashMap<br/>容量: 32<br/>阈值: 24]
                        
                        style A fill:#f9f,stroke:#333,stroke-width:2px
                        style B fill:#ff9,stroke:#333,stroke-width:2px
                        style C fill:#9ff,stroke:#333,stroke-width:2px
                        style D fill:#9ff,stroke:#333,stroke-width:2px
                        style E fill:#9ff,stroke:#333,stroke-width:2px
                        style F fill:#9f9,stroke:#333,stroke-width:2px
                </div>
            </div>
        </section>

        <!-- Impact Analysis -->
        <section class="mb-12">
            <h2 class="text-3xl font-bold mb-8 text-gray-800">
                <i class="fas fa-chart-line mr-3 text-purple-600"></i>扩容的影响分析
            </h2>
            <div class="grid md:grid-cols-2 gap-8">
                <div class="bg-red-50 rounded-2xl p-8 border-2 border-red-200">
                    <h3 class="text-2xl font-bold mb-4 text-red-700">
                        <i class="fas fa-exclamation-triangle mr-2"></i>性能开销
                    </h3>
                    <p class="text-gray-700 leading-relaxed">
                        扩容是一项开销较大的操作，因为它需要重新哈希和迁移所有现有的键值对。因此，在设计系统时，应尽量避免频繁触发扩容。通常可以通过指定合适的初始容量来减少扩容的次数。